package com.design;

import com.alibaba.fastjson.JSONArray;
import org.locationtech.jts.geom.*;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 多边形工具类
 *
 * @author liushuai
 */
public class GeometryUtils {
    private static final PrecisionModel DEFAULT_PRECISION_MODEL = new PrecisionModel(PrecisionModel.FIXED);
    private static final GeometryFactory DEFAULT_GEOMETRY_FACTORY = new GeometryFactory(DEFAULT_PRECISION_MODEL);

    public static final GeometryFactory FACTORY = DEFAULT_GEOMETRY_FACTORY;

    /**
     * 创建一个空的多边形
     *
     * @return an empty polygon
     */
    public static Polygon emptyPolygon() {
        return DEFAULT_GEOMETRY_FACTORY.createPolygon();
    }

    /**
     * 根据非闭合 坐标字符串 创建多边形
     * 非闭合 坐标字符串 格式例如："[[1389,370],[1490,469],[1612,473],[1478,374]]"
     * 参数格式不对会产生错误，请自行处理
     *
     * @param coordsStr 非闭合 坐标字符串
     * @return Polygon
     */
    public static Polygon createPolygon(String coordsStr) {
        // 将 违停区域坐标字符串 转换成 坐标点集合
        List<Coordinate> coords = JSONArray.parseArray(coordsStr)
                .toJavaList(int[].class)
                .stream().map(j -> new Coordinate(j[0], j[1]))
                .collect(Collectors.toList());
        // 闭合
        coords.add(new Coordinate(coords.get(0)));

        return DEFAULT_GEOMETRY_FACTORY.createPolygon(coords.toArray(new Coordinate[0]));
    }

    /**
     * 根据 几何图形 返回坐标字符串
     * 非通用转换工具，只做项目违停检测模块使用
     *
     * @return Polygon 格式例如："[[1389,370],[1490,469],[1612,473],[1478,374]]"
     */
    public static String coordsString(Geometry geometry) {
        StringBuffer result = new StringBuffer();
        result.append("[");

        if (geometry instanceof Polygon) {
            Polygon polygon = (Polygon) geometry;

            CoordinateSequence coordinateSequence = polygon.getExteriorRing().getCoordinateSequence();
            for (int i = 0; i < coordinateSequence.size() - 1; ++i) {
                if (i > 0) {
                    result.append(",");
                }
                result.append("[");
                result.append((int) coordinateSequence.getOrdinate(i, 0));
                result.append(",");
                result.append((int) coordinateSequence.getOrdinate(i, 1));
                result.append("]");
            }
        } else {
            throw new IllegalArgumentException("Unable to encode geometry " + geometry.getGeometryType());
        }
        result.append("]");
        return result.toString();
    }
}
